/*********************************************************************************************************
**
**                                   GJB 标准测试集
**
**                               Copyright All Rights Reserved
**
**--------------文件信息--------------------------------------------------------------------------------
**
** 文   件   名: gjb_S0101206GN_1.c
**
** 文件创建日期: 2021 年 1 月 12 日
**
** 描        述: 停止看门狗定时器
*********************************************************************************************************/

#ifdef SYLIXOS
#define __SYLIXOS_KERNEL
#endif

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
#include <pthread.h>
#include "signal.h"
#include <string.h>

#define MAX_WDG_NUM 64
#define SYSTEM_TICKS_USEC        1000
#define ECALLEDINISR                11
#define SYSTEM_TICKS_NANO        100000
#define EMNOTINITED 0x7A
#define FALSE                       0
#define TRUE                        1

typedef	unsigned char 	BOOL; 
typedef void (*wdg_func)(void *);
typedef int 			wdg_t;
typedef struct __wdg_attr
{
    unsigned int used;
    timer_t timerid;
    int ticks;
    int is_start;
    int is_execed;
    struct sigevent evp;
    void *args;
    wdg_func func;
}wdg_attr;
wdg_attr g_wdg[MAX_WDG_NUM];

unsigned long long g_pthread_delay_tick;
int is_set_sys_rate;
unsigned int g_sys_uleep_tick;
#include <stdlib.h>
static int nCount_tma_2061=5;

wdg_t wdg_id_tma_2061;

int pthread_delay(int ticks)
{
    g_pthread_delay_tick = ticks;
    sched_yield();
    if(is_set_sys_rate)
    {
        return usleep(g_sys_uleep_tick * ticks);
    }
    else
    {
        return usleep(SYSTEM_TICKS_USEC * ticks);
    }
}

int wdg_create(wdg_t *wdg_id)
{
    int id = 0;
    if(wdg_id == NULL)
        return -1;
    for(id = 1; id < MAX_WDG_NUM; id++)
    {
        if(g_wdg[id].used == 0)
            break;
    }
    if(id == MAX_WDG_NUM)
    {
        errno = EAGAIN;
        return -1;
    }
    g_wdg[id].used = 1;
    g_wdg[id].is_start = 0;
    //    wdg_t id=wdCreate();
    *wdg_id = id;
    //    printf("wdg_create %d\n", *wdg_id);
    return 0;
}

// TODO:该函数与glibc-2.28/sysdeps/mach/hurd/setitimer.c的函数有冲突
static void timer_thread(union sigval v)
{
    //    printf("timer_thread function! %d %d 0x%lx 0x%lx\n",
    //           v.sival_int,
    //           g_wdg[v.sival_int].is_execed,
    //            &g_wdg[v.sival_int].is_execed,
    //            g_wdg[v.sival_int].func);
    if(g_wdg[v.sival_int].func != NULL && (g_wdg[v.sival_int].is_execed == 0))
    {
        g_wdg[v.sival_int].is_execed = 1;
        g_wdg[v.sival_int].func(g_wdg[v.sival_int].args);
        //        printf("timer_thread set g_wdg[%d].is_execed %d 0x%lx\n",
        //               v.sival_int,
        //               g_wdg[v.sival_int].is_execed,
        //                &g_wdg[v.sival_int].is_execed);
    }
}
int wdg_start(wdg_t wdg_id,int ticks,void (*func)(void *arg),void *arg)
{
    int val;
    struct itimerspec it;
    if(wdg_id < 1 || wdg_id >= MAX_WDG_NUM)
    {
        errno = EAGAIN;
        return -1;
    }
    if ((func == NULL) && (arg == NULL))
    {
        return 0;
    }
    if(func == NULL)
    {
        return -1;
    }
    //    printf("wdg_start wdg_id  %d\n", wdg_id);
    memset(&g_wdg[wdg_id].evp, 0, sizeof(struct sigevent));
    g_wdg[wdg_id].evp.sigev_value.sival_int = wdg_id;                //也是标识定时器的，回调函数可以获得
    g_wdg[wdg_id].evp.sigev_notify = SIGEV_THREAD;                //线程通知的方式，派驻新线程
    g_wdg[wdg_id].evp.sigev_notify_function = timer_thread;               //线程函数地址
    g_wdg[wdg_id].func = func;
    g_wdg[wdg_id].args = arg;

    if(g_wdg[wdg_id].is_start == 0)
    {
        //    printf("timer_create %d\n", ticks);
        val = timer_create(CLOCK_REALTIME, &g_wdg[wdg_id].evp, &g_wdg[wdg_id].timerid);
        if(val < 0)
        {
            printf("timer_create err %d %d\n", val, errno);
            return val;
        }
        g_wdg[wdg_id].is_start = 1;
    }
    g_wdg[wdg_id].is_execed = 0;
    //    printf("set g_wdg[%d].is_execed %d 0x%lx\n",
    //           wdg_id,
    //           g_wdg[wdg_id].is_execed,
    //           &g_wdg[wdg_id].is_execed);
    g_wdg[wdg_id].ticks = ticks;
    it.it_interval.tv_sec = 0;
    it.it_interval.tv_nsec = g_wdg[wdg_id].ticks * SYSTEM_TICKS_NANO;
    it.it_value.tv_sec = 0;
    it.it_value.tv_nsec = 1000;//g_wdg[wdg_id].ticks * SYSTEM_TICKS_NANO;//1000

    //    printf("timer_settime\n");
    //    usleep(10);#include <stdlib.h>
    val = timer_settime(g_wdg[wdg_id].timerid, 0, &it, NULL);
    if(val < 0)
    {
        ;
        //        printf("timer_settime err %d %d\n", val, errno);
    }
    //    printf("timer_settime %d\n", val);
    //    val=wdStart(wdg_id,ticks,func,arg);
    return val;
}

int wdg_cancel(wdg_t wdg_id)
{
    if (wdg_id <= 0)
    {
        errno = EINVAL;
        return -1;
    }
    int ret;
    //    ret=wdCancel(wdg_id);
    struct itimerspec it;
    it.it_interval.tv_sec = 864000;
    it.it_interval.tv_nsec = g_wdg[wdg_id].ticks * SYSTEM_TICKS_NANO;
    it.it_value.tv_sec = 0;
    it.it_value.tv_nsec = 0;//g_wdg[wdg_id].ticks * SYSTEM_TICKS_NANO;//0
    g_wdg[wdg_id].is_execed = 1;

    ret = timer_settime(g_wdg[wdg_id].timerid, 0, &it, NULL);
    return ret;
}

void Fun1_tma_2061(void*arg)
{
    if (nCount_tma_2061 > 0) {
        nCount_tma_2061--;
        pthread_delay(50);
        wdg_start(wdg_id_tma_2061,100,Fun1_tma_2061,NULL);  // 启动看门狗

        if(nCount_tma_2061 == 1 )
        {
            wdg_cancel(wdg_id_tma_2061);

            //再次启动
            pthread_delay(50);
            wdg_start(wdg_id_tma_2061,100,Fun1_tma_2061,NULL);
        }
    }
}

int Test_Wdg_gn_tma_2061()
{
    int res;
    //创建看门狗
    res=wdg_create(&wdg_id_tma_2061);
    if(res==0)
    {
        printf("Pass--wdg_create(&wdg_id)\n");
    }
    else
    {
        printf("Fail--wdg_create(&wdg_id)\n");
        return -1;
    }
    //启动看门狗
    res=wdg_start(wdg_id_tma_2061,100,Fun1_tma_2061,NULL);
    if(res==0)
    {
        printf("Pass--wdg_start(wdg_id,100,Fun1,NULL)\n");
        return 0;
    }
    else
    {
        printf("Fail--wdg_start(wdg_id,100,Fun1,&cstr)\n");
        return -1;
    }
   return 0;
}
/**********************************************************************
 * 函数名称： void usrMain(void)
 * 功能描述： 用户程序入口
 * 输入参数： 无
 * 输出参数： 无
 * 返 回 值： 无
 * 其它说明： 无
 **************************************************************************/
int main()
{
    int  result;

    result = Test_Wdg_gn_tma_2061();
    if (result != 0) {
        printf("<RSLT>..................................................[GJB_FAILED]\n");
        return -1;
    }
    sleep(2);
    if (nCount_tma_2061!=0)   //5次是否执行完毕，则成功
    {
        printf("<RSLT>..................................................[GJB_FAILED]\n");
        return -1;
    }

    printf("<RSLT>..................................................[GJB_PASS]\n");
    return 0;
}
